package com.xu.tools.util;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;

/**
 * RestTemplate工具类
 *
 * @author xuguan
 * @since 2023/5/31
 */
public class RestTemplateUtil {
    private static final RestTemplate restTemplate = new RestTemplate();
    private static final HttpHeaders defaultHeaders = new HttpHeaders();
    private static final int CONNECT_TIMEOUT = 1000 * 3;
    private static final int READ_TIMEOUT = 1000 * 10;

    static {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(CONNECT_TIMEOUT);
        requestFactory.setReadTimeout(READ_TIMEOUT);
        restTemplate.setRequestFactory(requestFactory);

        defaultHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        defaultHeaders.add(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
    }

    public static <T> T doGet(String url, Class<T> responseType) {
        return restTemplate.getForObject(url, responseType);
    }

    public static <T> T doGet(String baseUrl, Map<String, String> params, HttpHeaders headers, Class<T> responseType) {
        HttpEntity<HttpHeaders> httpEntity = new HttpEntity<>(addHeaders(headers, defaultHeaders));
        return restTemplate.exchange(buildQueryUrl(baseUrl, params), HttpMethod.GET, httpEntity, responseType).getBody();
    }

    public static <T> T doPost(String url, String body, Class<T> responseType) {
        return restTemplate.postForObject(url, body, responseType);
    }

    public static <T> T doPost(String url, HttpHeaders headers, String body, Class<T> responseType) {
        HttpEntity<String> httpEntity = new HttpEntity<>(body, addHeaders(headers, defaultHeaders));
        return restTemplate.postForObject(url, httpEntity, responseType);
    }

    public static String buildQueryUrl(String baseUrl, Map<String, String> params) {
        if (CollectionUtils.isEmpty(params)) {
            return baseUrl;
        }

        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUriString(baseUrl);
        for (Map.Entry<String, String> entry : params.entrySet()) {
            uriComponentsBuilder.queryParam(entry.getKey(), entry.getValue());
        }
        return uriComponentsBuilder.toUriString();
    }

    private static HttpHeaders addHeaders(HttpHeaders customerHeaders, HttpHeaders defaultHeaders) {
        if (CollectionUtils.isEmpty(customerHeaders)) {
            return defaultHeaders;
        }
        defaultHeaders.forEach(customerHeaders::putIfAbsent);

        return customerHeaders;
    }
}
